package com.cogent.dynamicform.xml;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;

import com.cogent.common.util.Globals;
import com.cogent.common.util.StringUtil;
import com.cogent.common.util.XmlUtil;
import com.cogent.dynamicform.domain.BusControlDomain;
import com.cogent.dynamicform.domain.FormColumnDomain;
import com.cogent.dynamicform.domain.FormColumnSetDomain;
import com.cogent.dynamicform.domain.FormDomain;
import com.cogent.dynamicform.domain.FormQueryDynTableDomain;
import com.cogent.dynamicform.domain.FormViewDynTableDomain;
import com.cogent.dynamicform.util.DynamicFormBusUtil;
import com.cogent.validator.domain.ValidatorDomain;
import com.cogent.validator.xml.ValidatorXmlParse;

public class DynamicFormXmlParse {
	public static String DYNAMICFORM_RULE_FILE = Globals.getRootPath() + "WEB-INF/config/busform_config.xml";
	
	public static FormDomain parseForm(String formid) {
		FormDomain formDomain = new FormDomain();
		List list = new ArrayList();
		Document doc = XmlUtil.loadXmlFormFile(DYNAMICFORM_RULE_FILE);
		Node node = doc.selectSingleNode("//root/form[@id='" + formid + "']");
		if(node != null) {
			Element curElement = (Element)node;
			formDomain.setId(XmlUtil.getAttributeValue(curElement, "id"));
			formDomain.setMenuid(XmlUtil.getAttributeValue(curElement, "menuid"));
			formDomain.setCn(XmlUtil.getAttributeValue(curElement, "cn"));
			formDomain.setMaptable(XmlUtil.getAttributeValue(curElement, "maptable"));
			formDomain.setPrecode(XmlUtil.getAttributeValue(curElement, "precode"));
			formDomain.setListcolumn(XmlUtil.getAttributeValue(curElement, "listcolumn"));
			formDomain.setQuerycolumn(XmlUtil.getAttributeValue(curElement, "querycolumn"));
			formDomain.setMorequerycolumn(XmlUtil.getAttributeValue(curElement, "morequerycolumn"));
			formDomain.setSubtaps(XmlUtil.getAttributeValue(curElement, "subtaps"));
			formDomain.setParentid(XmlUtil.getAttributeValue(curElement, "parentid"));
			formDomain.setIsrecycle(StringUtil.toInt(XmlUtil.getAttributeValue(curElement, "isrecycle"), 1) > 0 ? true : false);
			formDomain.setBacksuffix(XmlUtil.getAttributeValue(curElement, "backsuffix"));
			formDomain.setParenttaps(XmlUtil.getAttributeValue(curElement, "parenttaps"));
			formDomain.setOpenlistcolumn(XmlUtil.getAttributeValue(curElement, "openlistcolumn"));
			formDomain.setIsmod(XmlUtil.getAttributeValue(curElement, "ismod").toLowerCase().equals("true") ? true : false);
			formDomain.setLinktaps(XmlUtil.getAttributeValue(curElement, "linktaps"));
			formDomain.setLinkmod(XmlUtil.getAttributeValue(curElement, "linkmod"));
			formDomain.setLinkid(XmlUtil.getAttributeValue(curElement, "linkid"));
			formDomain.setJscontrol(XmlUtil.getAttributeValue(curElement, "jscontrol"));
			formDomain.setUrlpost(XmlUtil.getAttributeValue(curElement, "urlpost"));
			formDomain.setCheckexist(XmlUtil.getAttributeValue(curElement, "checkexist"));
			formDomain.setCustomclass(XmlUtil.getAttributeValue(curElement, "customclass"));
			formDomain.setCustomtype(XmlUtil.getAttributeValue(curElement, "customtype"));
			formDomain.setOther(XmlUtil.getAttributeValue(curElement, "other"));
			formDomain.setOrderby(XmlUtil.getAttributeValue(curElement, "orderby"));
			formDomain.setOpenerlinktaps(XmlUtil.getAttributeValue(curElement, "openerlinktaps"));
			formDomain.setOpenertype(XmlUtil.getAttributeValue(curElement, "openertype"));
			formDomain.setOptname(XmlUtil.getAttributeValue(curElement, "optname"));
			formDomain.setChecklinktaps(XmlUtil.getAttributeValue(curElement, "checklinktaps"));
			formDomain.setOptprerequisites(XmlUtil.getAttributeValue(curElement, "optprerequisites"));
			if((!StringUtil.isEmpty(formDomain.getParenttaps())) && (StringUtil.isEmpty(formDomain.getOpenerlinktaps())))
				formDomain.setIsrecycle(false);
			formDomain.setIscache(StringUtil.toBooleanDefault(XmlUtil.getAttributeValue(curElement, "iscache"), false));
			formDomain.setOperatorbut(XmlUtil.getAttributeValue(curElement, "operatorbut"));
			if(StringUtil.isEmpty(formDomain.getOperatorbut()))
				formDomain.setOperatorbut("RECYCLE");
			formDomain.setOperatorjs(XmlUtil.getAttributeValue(curElement, "operatorjs"));
			formDomain.setReturntype(XmlUtil.getAttributeValue(curElement, "returntype"));
			formDomain.setCustomhelper(XmlUtil.getAttributeValue(curElement, "customhelper"));
			formDomain.setFormmapfield(XmlUtil.getAttributeValue(curElement, "formmapfield"));
			formDomain.setUrlpath(XmlUtil.getAttributeValue(curElement, "urlpath"));
			formDomain.setViewmod(XmlUtil.getAttributeValue(curElement, "viewmod"));
			formDomain.setFormsubmitjs(XmlUtil.getAttributeValue(curElement, "formsubmitjs"));
			formDomain.setOptshowintype(XmlUtil.getAttributeValue(curElement, "optshowintype"));
			formDomain.setCacherefreshcode(XmlUtil.getAttributeValue(curElement, "cacherefreshcode"));
			formDomain.setIsworkflow(XmlUtil.getAttributeValue(curElement, "isworkflow").toLowerCase().equals("true") ? true : false);
			formDomain.setQueryprefix(XmlUtil.getAttributeValue(curElement, "queryprefix").toLowerCase().equals("true") ? true : false);
			formDomain.setCustomvalidator(XmlUtil.getAttributeValue(curElement, "customvalidator"));
			formDomain.setOptbtntype(StringUtil.toInt(XmlUtil.getAttributeValue(curElement, "optbtntype")));
			formDomain.setIsdelete(XmlUtil.getAttributeValue(curElement, "isdelete").toLowerCase().equals("true") ? true : false);
			formDomain.setDelattribute(XmlUtil.getAttributeValue(curElement, "delattribute"));
			List columnList = new ArrayList();
			List allcolumnList = new ArrayList();
			Map columnMap = new HashMap();
			List nodeList = node.selectNodes("column");
			Iterator it = nodeList.iterator();
			while(it.hasNext()) {
				Element e = (Element)it.next();
				FormColumnDomain formColumnDomain = parseFormColumnDomain(e);
				columnList.add(formColumnDomain);
				allcolumnList.add(formColumnDomain);
				columnMap.put(formColumnDomain.getName(), formColumnDomain);
			}
			formDomain.setColumnList(columnList);
			List setnodeList = node.selectNodes("columnset");
			List fromcolumnsetList = new ArrayList();
			Iterator curit2 = setnodeList.iterator();
			while(curit2.hasNext()) {
				Node curNode = (Node)curit2.next();
				Element e = (Element)curNode;
				FormColumnSetDomain formColumnSetDomain = new FormColumnSetDomain();
				formColumnSetDomain.setCn(XmlUtil.getAttributeValue(e, "cn"));
				formColumnSetDomain.setRowspan(StringUtil.toInt(XmlUtil.getAttributeValue(e, "rowspan"), 1));
				List columnsetList = curNode.selectNodes("column");
				Iterator setit = columnsetList.iterator();
				List setColunmList = new ArrayList();
				while(setit.hasNext()) {
					Element sete = (Element)setit.next();
					FormColumnDomain formColumnDomain = parseFormColumnDomain(sete);
					setColunmList.add(formColumnDomain);
					allcolumnList.add(formColumnDomain);
					columnMap.put(formColumnDomain.getName(), formColumnDomain);
				}
				formColumnSetDomain.setColumnList(setColunmList);
				fromcolumnsetList.add(formColumnSetDomain);
			}
			formDomain.setColumnSetList(fromcolumnsetList);
			Node workFlownode= node.selectSingleNode("./workFlow");
			if(workFlownode != null) {
				List columnsetList = workFlownode.selectNodes("column");
				Iterator setit = columnsetList.iterator();
				List workFlowColunmList = new ArrayList();
				while(setit.hasNext()) {
					Element sete = (Element)setit.next();
					FormColumnDomain formColumnDomain = parseFormColumnDomain(sete);
					workFlowColunmList.add(formColumnDomain);
					allcolumnList.add(formColumnDomain);
					columnMap.put(formColumnDomain.getName(), formColumnDomain);
				}
				formDomain.setWorkFlowList(workFlowColunmList);
				formDomain.setIsworkflow(true);
			}
			formDomain.setAllcolumnList(allcolumnList);
			formDomain.setColumnMap(columnMap);
			Node queynode= node.selectSingleNode("./query");
			Map curcolumnMap = null;
			if(queynode != null) {
				curcolumnMap = new HashMap();
				formDomain.setQuerysql(XmlUtil.getCdataValue(queynode));
				List querynodeList = queynode.selectNodes("column");
				Iterator it2 = querynodeList.iterator();				
				while(it2.hasNext()) {
					Element e = (Element)it2.next();
					FormColumnDomain formColumnDomain = parseFormColumnDomain(e);
					curcolumnMap.put(formColumnDomain.getName(), formColumnDomain);
				}
			} else
				curcolumnMap = formDomain.getColumnMap();		
			Node dynTablenode= node.selectSingleNode("./dynTable");
			if(dynTablenode != null) {
				formDomain.setDynTableCn(XmlUtil.getAttributeValue((Element)dynTablenode, "cn"));
				formDomain.setDynTableParentid(XmlUtil.getAttributeValue((Element)dynTablenode, "parentid"));
				formDomain.setDynTableName(XmlUtil.getAttributeValue((Element)dynTablenode, "maptable"));
				formDomain.setDynTableParentkeys(XmlUtil.getAttributeValue((Element)dynTablenode, "parentkeys"));
				formDomain.setDynTableOrderBy(XmlUtil.getAttributeValue((Element)dynTablenode, "orderby"));
				formDomain.setDyntableoperatname(XmlUtil.getAttributeValue((Element)dynTablenode, "dyntableoperatname"));
				formDomain.setDynTabletype(XmlUtil.getAttributeValue((Element)dynTablenode, "dyntabletype"));
				formDomain.setDyntableoperatid(XmlUtil.getAttributeValue((Element)dynTablenode, "dyntableoperatid"));
				formDomain.setDyntableoperattitle(XmlUtil.getAttributeValue((Element)dynTablenode, "dyntableoperattitle"));
				formDomain.setDynTableViewmodel(StringUtil.toInt(XmlUtil.getAttributeValue((Element)dynTablenode, "viewmodel"), 0));
				List dynTablenodeList = dynTablenode.selectNodes("column");
				Iterator curit = dynTablenodeList.iterator();
				List dynTableList = new ArrayList();
				while(curit.hasNext()) {
					Element e = (Element)curit.next();
					FormColumnDomain formColumnDomain = parseFormColumnDomain(e);
					dynTableList.add(formColumnDomain);
				}
				formDomain.setDynTableList(dynTableList);
			}
			formDomain.setBusControlList(parseBuscontrol(node.selectSingleNode("./buscontrol")));
			formDomain.setQueryList(DynamicFormBusUtil.getFormQueryList(formDomain, curcolumnMap));
			formDomain.setListColumnList(DynamicFormBusUtil.getListColumn(formDomain, curcolumnMap));
			if(StringUtil.isEmpty(formDomain.getOpenlistcolumn()))
				formDomain.setOpenlistColumnList(formDomain.getListColumnList());
			else
				formDomain.setOpenlistColumnList(DynamicFormBusUtil.getListColumn(formDomain.getOpenlistcolumn(), formDomain.getColumnMap()));
			Node viewDynTable= node.selectSingleNode("./viewDynTable");
			if(viewDynTable != null) {
				FormViewDynTableDomain formViewDynTableDomain = new FormViewDynTableDomain();
				formViewDynTableDomain.setCn(XmlUtil.getAttributeValue((Element)viewDynTable, "cn"));
				formViewDynTableDomain.setMaptable(XmlUtil.getAttributeValue((Element)viewDynTable, "maptable"));
				formViewDynTableDomain.setParentid(XmlUtil.getAttributeValue((Element)viewDynTable, "parentid"));
				formViewDynTableDomain.setOrderby(XmlUtil.getAttributeValue((Element)viewDynTable, "orderby"));
				formViewDynTableDomain.setMapparentid(XmlUtil.getAttributeValue((Element)viewDynTable, "mapparentid"));
				List dynTablenodeList = viewDynTable.selectNodes("column");
				Iterator curit = dynTablenodeList.iterator();
				List dynTableList = new ArrayList();
				while(curit.hasNext()) {
					Element e = (Element)curit.next();
					FormColumnDomain formColumnDomain = parseFormColumnDomain(e);
					dynTableList.add(formColumnDomain);
				}
				formViewDynTableDomain.setDynTableList(dynTableList);
				formDomain.setViewDynTableDomain(formViewDynTableDomain);
			}
			Node vqueryDynTable = node.selectSingleNode("./queryDynTable");
			if(vqueryDynTable != null) {
				FormQueryDynTableDomain formQueryDynTableDomain = new FormQueryDynTableDomain();
				formQueryDynTableDomain.setCn(XmlUtil.getAttributeValue((Element)vqueryDynTable, "cn"));
				formQueryDynTableDomain.setMaptable(XmlUtil.getAttributeValue((Element)vqueryDynTable, "maptable"));
				formQueryDynTableDomain.setParentid(XmlUtil.getAttributeValue((Element)vqueryDynTable, "parentid"));
				formQueryDynTableDomain.setOrderby(XmlUtil.getAttributeValue((Element)vqueryDynTable, "orderby"));
				formQueryDynTableDomain.setMapparentid(XmlUtil.getAttributeValue((Element)vqueryDynTable, "mapparentid"));
				formQueryDynTableDomain.setQuerysql(XmlUtil.getAttributeValue((Element)vqueryDynTable, "querysql"));
				List dynTablenodeList = vqueryDynTable.selectNodes("column");
				Iterator curit = dynTablenodeList.iterator();
				List dynTableColumnList = new ArrayList();
				while(curit.hasNext()) {
					Element e = (Element)curit.next();
					FormColumnDomain formColumnDomain = parseFormColumnDomain(e);
					dynTableColumnList.add(formColumnDomain);
				}
				formQueryDynTableDomain.setDynTableColumnList(dynTableColumnList);
				formDomain.setQueryDynTableDomain(formQueryDynTableDomain);
			}
			formDomain.setValidatorList(DynamicFormBusUtil.getValidatorList(formDomain.getAllcolumnList()));
		}
		if(!StringUtil.isEmpty(formDomain.getMorequerycolumn()))
			formDomain.setIsmorequery(true);
		
		return formDomain;
	}
	
	private static FormColumnDomain parseFormColumnDomain(Element e) {
		FormColumnDomain formColumnDomain = new FormColumnDomain();
		String name = XmlUtil.getAttributeValue(e, "name");
		formColumnDomain.setName(name);
		String cn = XmlUtil.getAttributeValue(e, "cn");
		formColumnDomain.setCn(cn);
		formColumnDomain.setOpttype(XmlUtil.getAttributeValue(e, "opttype"));
		formColumnDomain.setType(XmlUtil.getAttributeValue(e, "type"));
		formColumnDomain.setTypecode(XmlUtil.getAttributeValue(e, "typecode"));
		String validator = XmlUtil.getAttributeValue(e, "validator");
		formColumnDomain.setIsrequired(isRequired(validator));
		formColumnDomain.setNotemsg(XmlUtil.getAttributeValue(e, "notemsg"));
		formColumnDomain.setRowspan(StringUtil.toInt(XmlUtil.getAttributeValue(e, "rowspan"), 1));
		formColumnDomain.setColspan(StringUtil.toInt(XmlUtil.getAttributeValue(e, "colspan"), 1));
		formColumnDomain.setShowclass(XmlUtil.getAttributeValue(e, "showclass"));
		formColumnDomain.setJs(XmlUtil.getAttributeValue(e, "js"));
		formColumnDomain.setDefaultvalue(XmlUtil.getAttributeValue(e, "defaultvalue"));
		formColumnDomain.setShowcontrol(XmlUtil.getAttributeValue(e, "showcontrol"));
		formColumnDomain.setExpression(XmlUtil.getAttributeValue(e, "expression"));
		formColumnDomain.setCalformula(XmlUtil.getAttributeValue(e, "calformula"));
		formColumnDomain.setPopfullup(XmlUtil.getCdataValue(e, "./popfullup"));
		formColumnDomain.setViewmodel(StringUtil.toInt(XmlUtil.getAttributeValue(e, "viewmodel")));
		formColumnDomain.setShowtype(StringUtil.toInt(XmlUtil.getAttributeValue(e, "showtype")));
		String mapedfileld = XmlUtil.getAttributeValue(e, "mapedfileld");
		if(StringUtil.isEmpty(mapedfileld))
			mapedfileld = formColumnDomain.getName();
		formColumnDomain.setMapedfileld(mapedfileld);
		formColumnDomain.setTablename(XmlUtil.getAttributeValue(e, "tablename"));
		formColumnDomain.setShowparam(XmlUtil.getAttributeValue(e, "showparam"));
		formColumnDomain.setCountexpression(XmlUtil.getAttributeValue(e, "countexpression"));
		if(formColumnDomain.getViewmodel() > 0)
			formColumnDomain.setValidator(new ArrayList());
		else
			formColumnDomain.setValidator(getValidatorList(cn, name, validator));
		
		return formColumnDomain;
	}
	
	private static List<BusControlDomain> parseBuscontrol(Node n) {
		List<BusControlDomain> list = null;
		if(n != null) {
			list = new ArrayList<BusControlDomain>();
			List nodelist = n.selectNodes("control");
			Iterator it = nodelist.iterator();
			while(it.hasNext()) {
				Element e = (Element)it.next();
				BusControlDomain busControlDomain = new BusControlDomain();
				busControlDomain.setType(XmlUtil.getAttributeValue(e, "type"));
				busControlDomain.setInfo(XmlUtil.getAttributeValue(e, "info"));
				busControlDomain.setPrerequisites(XmlUtil.getAttributeValue(e, "prerequisites"));
				list.add(busControlDomain);
			}
		}
		
		return list;
	}
	
	private static List getValidatorList(String key, String property, String validator) {
		List list = new ArrayList();
		if(!StringUtil.isEmpty(validator)) {
			String[] curenum = validator.split(";");
			for(int i=0; i<curenum.length; i++) {
				String[] nextenmu = curenum[i].split("~");
				ValidatorDomain validatorDomain = new ValidatorDomain();
				validatorDomain.setKey(key);
				validatorDomain.setProperty(property);
				validatorDomain.setValidator(nextenmu[0]);
				String keyPair = "";
				if(nextenmu.length > 1)
					keyPair = nextenmu[1];
				String noteMsg = "";
				if(nextenmu.length > 2)
					noteMsg = nextenmu[2];
				validatorDomain.setNotemsg(noteMsg);
				validatorDomain.setKeypairmap(ValidatorXmlParse.stringToMap(keyPair));
				list.add(validatorDomain);
			}
		}
		
		return list;
	}
	
	private static boolean isRequired(String validator) {
		boolean flag =false;
		if(validator.indexOf("required") > -1)
			flag = true;
		
		return flag;
	}
}
